package cn.msqweb.src.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.msqweb.constant.BusinessEnum;
import cn.msqweb.entity.Member;
import cn.msqweb.entity.MemberAddr;
import cn.msqweb.entity.Order;
import cn.msqweb.entity.OrderItem;
import cn.msqweb.model.Result;
import cn.msqweb.src.feign.OrderMemberFeign;
import cn.msqweb.src.mapper.OrderITemMapper;
import cn.msqweb.src.mapper.OrderMapper;
import cn.msqweb.src.service.OrderService;
import cn.msqweb.src.vo.OrderStatusCount;
import cn.msqweb.util.AuthUtils;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 20120
 * @description 针对表【order(订单表)】的数据库操作Service实现
 * @createDate 2024-06-24 20:08:52
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
        implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderITemMapper orderItemMapper;

    @Resource
    private OrderMemberFeign orderMemberFeign;

    @Override
    public Page<Order> querySysOrderPage(Long current, Long size, String orderNumber, Integer status, Date startTime, Date endTime) {
        Page<Order> page = new Page<>(current, size);
        // 多条件分页查询订单
        page = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
                .eq(ObjectUtil.isNotNull(status), Order::getStatus, status)
                .eq(StringUtils.hasText(orderNumber), Order::getOrderNumber, orderNumber)
                .between(ObjectUtil.isAllNotEmpty(startTime, endTime), Order::getCreateTime, startTime, endTime)
                .orderByDesc(Order::getCreateTime)
        );
        // 从分页对象中获取订单记录
        List<Order> orderList = page.getRecords();
        // 判断是否有值
        if (CollectionUtil.isNotEmpty(orderList) && orderList.size() != 0) {
            // 从订单集合中获取订单编号
            List<String> orderNumbers = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
            // 根据标识编号集合查询订单商品条目对象集合
            List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                    .in(OrderItem::getOrderNumber, orderNumbers)
            );

            // 循环遍历订单对象集合
            orderList.forEach(order -> {
                // 从订单商品条目对象集合中过滤出订单商品条目对象与订单对象的订单编号一致的订单商品条目对象集合
                List<OrderItem> orderItems = orderItemList.stream()
                        .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                        .collect(Collectors.toList());
                order.setOrderItems(orderItems);
            });
        }
        return page;
    }

    @Override
    public Order querySysOrderInfoByOrderNumber(String orderNumber) {
        // 根据订单编号查询订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)
        );

        // 根据订单编号查询订单的商品条目集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, orderNumber)
        );
        order.setOrderItems(orderItemList);

        // 远程调用：查询订单会员名称
        Result<Member> result = orderMemberFeign.getMemberByOpenId(order.getOpenId());
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new RuntimeException("远程调用：查询订单会员名称失败");
        }
        Member member = result.getData();
        order.setNickName(member.getNickName());


        // TODO 远程调用：查询订单的收货地址信息
        MemberAddr memberAddr = new MemberAddr();
        order.setUserAddrOrder(memberAddr);
        return order;
    }


    //////微信小程序
    @Override
    public OrderStatusCount selectOrderStatusByOpenId(String loginMemberOpenId) {
        OrderStatusCount orderStatusCount = new OrderStatusCount();
        List<Order> orders = orderMapper.selectList(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, loginMemberOpenId)
                .eq(Order::getDeleteStatus, 0)
        );
        Map<Integer, Integer> result = orders.stream().collect(Collectors.groupingBy(
                Order::getStatus,
                Collectors.reducing(0, e -> 1, Integer::sum)
        ));
        orderStatusCount.setUnPay(result.getOrDefault(1, 0).longValue());
        orderStatusCount.setPayed(result.getOrDefault(2, 0).longValue());
        orderStatusCount.setConsignment(result.getOrDefault(3, 0).longValue());
        return orderStatusCount;
    }


    @Override
    public Page<Order> queryMemberOrderPageByOpenId(Long current, Long size, Integer status) {
        Page<Order> page = new Page<>(current, size);
        String loginMemberOpenId = AuthUtils.getLoginMemberOpenId();
        Page<Order> orderPage = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, loginMemberOpenId)
                .eq(Order::getDeleteStatus,0)
                .eq(0 != status, Order::getStatus, status)
                .orderByDesc(Order::getCreateTime));
        List<Order> records = orderPage.getRecords();
        if (CollectionUtil.isNotEmpty(records) && records.size() != 0){
            List<String> orderList = records.stream().map(Order::getOrderNumber).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                    .in(OrderItem::getOrderNumber, orderList));
            records.forEach(
                    order -> {
                        List<OrderItem> orderItemsFilter = orderItems.stream().filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber())).collect(Collectors.toList());
                        order.setOrderItemDtos(orderItemsFilter);
                    }
            );
        }
        return page;
    }

    @Override
    public Order queryWxOrderDetailByOrderNumber(String orderNumber) {
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber));
        //远程调用
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(order.getAddrOrderId());
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())){
            throw new RuntimeException("远程调用失败");
        }
        MemberAddr data = result.getData();
        order.setUserAddrDto(data);
        List<OrderItem> orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, order.getOrderNumber()));
        order.setOrderItemDtos(orderItems);
        return order;
    }

    @Override
    public Boolean receiptMemberOrder(String orderNumber) {
        return orderMapper.update(Order.builder()
                .status(5)
                .updateTime(new Date())
                .finallyTime(new Date()).build(),
                new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)) > 0;
    }

    @Override
    public Boolean removeMemberOrderByOrderNumber(String orderNumber) {
        Order order = new Order();
        order.setDeleteStatus(2);
        order.setUpdateTime(new Date());
        int update = orderMapper.update(order, new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber));
        return update > 0;
    }

    @Override
    public Boolean cancelMemberOrder(String orderNumber) {
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setFinallyTime(new Date());
        order.setCancelTime(new Date());
        order.setCloseType(4);
        order.setStatus(6);
        return orderMapper.update(order,new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber,orderNumber)
        )>0;
    }


}




